home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Panorama / Panorama - Disk 01 (1986-02-15)(Pacific North-West Amigas Club)[h AFL][b corrupt files].zip / Panorama - Disk 01 (1986-02-15)(Pacific North-West Amigas Club)[h AFL][b corrupt files].adf / mand3.c < prev    next >
Text File  |  1989-10-24  |  18KB  |  575 lines

  1. /*
  2.                   MAND3.C - Control routines
  3.              Mandelbrot Self-Squared Dragon Generator
  4.                     For the Commodore Amiga
  5.                          Version 2.01
  6.  
  7.              Copyright (C) 1985, Robert S. French
  8.             Vastly Enhanced by =RJ Mical=  1985/86
  9.             Copyright (C) 1986,  =Robert J. Mical=
  10.                  Placed in the Public Domain
  11.  
  12.  
  13. This program may be distributed free of charge as long as the above
  14. notice is retained.
  15.  
  16. */
  17.  
  18.  
  19. #include "mand.h"
  20.  
  21.  
  22. extern int MathBase, MathTransBase;
  23.  
  24. extern struct Menu MainMenu[MENU_COUNT];
  25. extern struct MenuItem OptionsItems[OPTIONS_COUNT];
  26.  
  27. extern SHORT Color0, Color1, Color2;
  28. extern SHORT UserPalette[29];
  29.  
  30. extern BOOL SavePicture();
  31.  
  32.  
  33. /*----------------------*/
  34. /* Graphics definitions */
  35.  
  36. extern struct   GfxBase       *GfxBase;
  37. extern struct   IntuitionBase *IntuitionBase;
  38.  
  39. struct   RastPort      *rp,*rp2;
  40. struct   ViewPort      *vp;
  41.  
  42. struct TextAttr TextFont =
  43.     {
  44.     "topaz.font", /* Standard system font */
  45.     8,    0,    0
  46.     };
  47.  
  48. struct   Window        *w,*w2, ColorWindow;
  49. struct   Screen        *screen;
  50. struct   IntuiMessage  *message;
  51.  
  52. struct NewScreen ns = {
  53.    0, 0,                               /* start position                */
  54.    320, 200, 6,                        /* width, height, depth          */
  55.    0, 1,                               /* detail pen, block pen         */
  56.    HAM,                                /* Hold and Modify ViewMode      */
  57.    CUSTOMSCREEN,                       /* screen type                   */
  58.    &TextFont,                          /* font to use                   */
  59.    "",                                 /* default title for screen      */
  60.    NULL                                /* pointer to additional gadgets */
  61.    };
  62.  
  63. struct NewWindow nw = {
  64.    0, 0,                          /* start position                */
  65.    320, 200,                      /* width, height                 */
  66.    -1, -1,                        /* detail pen, block pen         */
  67.    MOUSEBUTTONS | MENUPICK | INTUITICKS,
  68.                                   /* IDCMP flags                   */
  69.    ACTIVATE | BORDERLESS | BACKDROP,
  70.                                   /* window flags                  */
  71.    NULL,                          /* pointer to first user gadget  */
  72.    NULL,                          /* pointer to user checkmark     */
  73.    NULL,                          /* window title                  */
  74.    NULL,                          /* pointer to screen (set below) */
  75.    NULL,                          /* pointer to superbitmap        */
  76.    0, 0, 320, 200,                /* ignored since not sizeable    */
  77.    CUSTOMSCREEN                   /* type of screen desired        */
  78. };
  79.  
  80. struct NewWindow aw = {
  81.    0, 10,
  82.    100, 70,
  83.    -1, -1,
  84.    NULL,
  85.    WINDOWDRAG|WINDOWSIZING|SMART_REFRESH,
  86.    NULL,
  87.    NULL,
  88.    "Analysis",
  89.    NULL,
  90.    NULL,
  91.    0, 0, 320, 200,
  92.    CUSTOMSCREEN
  93. };
  94.  
  95. long last_color;
  96.  
  97. BOOL SettingCenter, SettingBoxSize, SetBoxProportional;
  98.  
  99. /*----------------------------------*/
  100. /* Miscellaneous Global Definitions */
  101.  
  102. extern union kludge {
  103.    float f;
  104.    int i;
  105. } start_r,end_r,start_i,end_i;  /* Block bounds for set */
  106. extern int max_x,max_y;  /* Graphics window size */
  107. extern int max_count,color_inc,color_offset,color_set,color_mode,color_div;
  108. extern int color_inset,func_num;
  109.  
  110. extern int v_starty,max_mem, max_mem_y;
  111. extern long v_offset;
  112. extern UWORD *color_table,*v_mand_store;
  113.  
  114. extern int modified,want_read;
  115.  
  116. extern FILE *console,*v_fp,*redir_fp;
  117.  
  118. extern SHORT ZoomCenterX, ZoomCenterY, ZoomBoxSizeX, ZoomBoxSizeY;
  119. extern SHORT ZoomBoxStartX, ZoomBoxStartY;
  120.  
  121.  
  122. open_winds()
  123. {
  124.    int i,color;
  125.  
  126.    nw.Width = max_x;
  127.    nw.Height = max_y+STARTY;
  128.  
  129.    if (color_mode & NOT_HOLDANDMODIFY) {
  130.       ns.ViewModes = NULL;
  131.       ns.Depth = 5;
  132.    }
  133.    else {
  134.       ns.ViewModes = HAM;
  135.       ns.Depth = 6;
  136.    }
  137.  
  138.    if (color_mode & INTERLACE_MODE) {
  139.       ns.Height = 400;
  140.    }
  141.    else
  142.       ns.Height = 200;
  143.  
  144.    if (color_mode & HIRES_MODE) {
  145.       ns.Width = 640;
  146.       ns.ViewModes |= HIRES;
  147.       ns.Depth = 4;
  148.    }
  149.    else
  150.       ns.Width = 320;
  151.  
  152.    screen = (struct Screen *)OpenScreen(&ns);
  153.    if (screen == NULL) {
  154.       fputs("Can't open new screen!\n",console);
  155.       return (1);
  156.    }
  157.  
  158.    ShowTitle(screen,FALSE);
  159.  
  160.    nw.Screen = screen;
  161.    w = (struct Window *)OpenWindow(&nw);
  162.    if (w == NULL) {
  163.       CloseScreen(screen);
  164.       fputs("Can't open new window!\n",console);
  165.       return (1);
  166.    }
  167.  
  168.    /* Until we're done drawing the primary display, cripple the menu system */
  169.    MainMenu[MENU_OPTIONS].NextMenu = NULL;
  170.    MainMenu[MENU_OPTIONS].FirstItem = &OptionsItems[OPTIONS_STOP];
  171.    SetMenuStrip(w, &MainMenu[MENU_OPTIONS]);
  172.  
  173.    vp = &screen->ViewPort;
  174.    rp = w->RPort;
  175.  
  176.    SetDrMd(rp,JAM1);
  177.    SetBPen(rp, 0);
  178.  
  179.    /* leave registers 0 and 1 alone, set two to black, set the others
  180.     * according to the user's design
  181.     */
  182.    SetRGB4(vp, 0, (Color0 >> 8) & 0xf, (Color0 >> 4) & 0xf, Color0 & 0xf);
  183.    SetRGB4(vp, 1, (Color1 >> 8) & 0xf, (Color1 >> 4) & 0xf, Color1 & 0xf);
  184.    SetRGB4(vp, 2, (Color2 >> 8) & 0xf, (Color2 >> 4) & 0xf, Color2 & 0xf);
  185.    for (i = 3; i <= 31; i++) {
  186.       UserPalette[i - 3] = 
  187.             color = *(color_table + color_offset + (i - 2) * color_inc);
  188.       SetRGB4(vp, i, (color >> 8) & 0xf, (color >> 4) & 0xf, color & 0xf);
  189.    }
  190.  
  191.    return (0);
  192. }
  193.  
  194. void wait_close()
  195. {
  196.    ULONG class;
  197.    USHORT code;
  198.  
  199.    if (redir_fp)
  200.       {
  201.       Delay(600);
  202.       CloseDisplay();
  203.       return;
  204.       }
  205.  
  206.    SettingCenter = SettingBoxSize = FALSE;
  207.  
  208.    for (EVER)
  209.       {
  210.       Wait((1 << w->UserPort->mp_SigBit));
  211.       while (message = (struct IntuiMessage *)GetMsg(w->UserPort))
  212.          {
  213.          class = message->Class;
  214.          code  = message->Code;
  215.          ReplyMsg(message);
  216.  
  217.          switch (class)
  218.             {
  219.             case MENUPICK:
  220.                switch MENUNUM(code)
  221.                   {
  222.                   case MENU_PROJECT:
  223.                      if (ProjectMenu(code)) return;
  224.                      break;
  225.                   case MENU_OPTIONS:
  226.                      if (DisplayMenu(code)) return;
  227.                      break;
  228.                   case MENU_ZOOM:
  229.                      if (ZoomMenu(code)) return;
  230.                      break;
  231.                   }
  232.                break; /* breaks MENUPICK switch statement */
  233.             case INTUITICKS:
  234.               code = NULL;
  235.             case MOUSEBUTTONS:
  236.               if (SettingCenter)
  237.                  {
  238.                  DrawZoomCenter();
  239.                  if (code == SELECTDOWN) 
  240.                     {
  241.                     SettingCenter = FALSE;
  242.                     DrawDisplayCenter();
  243.                     }
  244.                  else
  245.                     {
  246.                     ZoomCenterX = w->MouseX;
  247.                     ZoomCenterY = w->MouseY;
  248.                     DrawZoomCenter();
  249.                     }
  250.                  }
  251.               else if (SettingBoxSize)
  252.                  {
  253.                  DrawZoomBox();
  254.                  if (code == SELECTDOWN) SettingBoxSize = FALSE;
  255.                  else
  256.                     {
  257.                     RecalcZoomBox();
  258.                     DrawZoomBox();
  259.                     }
  260.                  }
  261.               break;
  262.             }
  263.          }
  264.       }
  265. }
  266.  
  267.  
  268. anal_mand()
  269. {
  270.    union kludge x_gap,y_gap,z_r,z_i,u_r,u_i,const0,const1,const2,const4;
  271.    union kludge const12,temp,temp2,temp3;
  272.    int count,x,y,width,height,last_x,last_y,select,lines;
  273.    ULONG class;
  274.    USHORT code;
  275.  
  276.    if (disp_mand())
  277.       return (1);
  278.  
  279.    x_gap.i = SPDiv(SPFlt(max_x),SPSub(start_r.i,end_r.i));
  280.    y_gap.i = SPDiv(SPFlt(max_y),SPSub(start_i.i,end_i.i));
  281.  
  282.    const0.i = SPFlt(0);
  283.    const1.i = SPFlt(1);
  284.    const2.i = SPFlt(2);
  285.    const4.i = SPFlt(4);
  286.    const12.i = SPDiv(SPFlt(2),SPFlt(1));
  287.  
  288.    last_x = -1;
  289.    last_y = -1;
  290.    select = 0;
  291.    lines = 0;
  292.  
  293.    aw.Screen = screen;
  294.    w2 = (struct Window *)OpenWindow(&aw);
  295.    if (w2 == NULL)
  296.    {
  297.       CloseDisplay();
  298.       fputs("Can't open analyzing window\n",console);
  299.       return (1);
  300.    }
  301.  
  302.    rp2 = w2->RPort;
  303.  
  304.    SetDrMd(rp2,JAM1);
  305.    SetBPen(rp2, 0);
  306.  
  307.    SetAPen(rp2, 1);
  308.    RectFill(rp2,LEFTW2+1,TOPW2+1,RIGHTW2-1,BOTTOMW2-1);
  309.  
  310.    for (EVER) {
  311.       if (message = (struct IntuiMessage *)GetMsg(w->UserPort)) {
  312.          class = message->Class;
  313.          code  = message->Code;
  314.          ReplyMsg(message);
  315.  
  316.          if (class == CLOSEWINDOW) {
  317.             CloseWindow(w2);
  318.             CloseDisplay();
  319.             return (0);
  320.          }
  321.          if (class == MOUSEBUTTONS)
  322.             if (code == SELECTDOWN) {
  323.                if (w->MouseY < STARTY)
  324.                   lines = !lines;
  325.                else
  326.                   select = TRUE;
  327.             }
  328.             else if (code == SELECTUP)
  329.                select = FALSE;
  330.       }
  331.       if ((last_x != w->MouseX || last_y != w->MouseY) && select &&
  332.           w->MouseX < max_x && w->MouseY >= STARTY && w->MouseY < max_y+STARTY) {
  333.          last_x = w-> MouseX;
  334.          last_y = w-> MouseY;
  335.          SetAPen(rp2,1);
  336.          RectFill(rp2,LEFTW2+1,TOPW2+1,RIGHTW2-1,BOTTOMW2-1);
  337.          width = RIGHTW2 - LEFTW2 - 6;
  338.          height = BOTTOMW2 - TOPW2 - 4;
  339.          SetAPen(rp2,3);
  340.          Move(rp2,LEFTW2+2,TOPW2+height/2+2);
  341.          Draw(rp2,RIGHTW2-2,TOPW2+height/2+2);
  342.          Move(rp2,LEFTW2+width/2+3,TOPW2+2);
  343.          Draw(rp2,LEFTW2+width/2+3,BOTTOMW2-2);
  344.          SetAPen(rp2,2);
  345.          if (func_num == 0)
  346.             z_r.i = const0.i;
  347.          else
  348.             z_r.i = const12.i;
  349.          z_i.i = const0.i;
  350.          u_r.i = SPAdd(start_r.i,SPMul(SPFlt(last_x),x_gap.i));
  351.          u_i.i = SPAdd(start_i.i,SPMul(SPFlt(max_y-(last_y-STARTY)-1),y_gap.i));
  352.          count = 0;
  353.          for (count=0;SPFix(SPAdd(SPMul(z_r.i,z_r.i),SPMul(z_i.i,z_i.i)))<4&&(count<max_count);count++) {
  354.  
  355.             temp.i = SPDiv(const4.i,SPMul(z_r.i,SPFlt(width)));
  356.             x = SPFix(temp.i);
  357.             temp.i = SPDiv(const4.i,SPMul(z_i.i,SPFlt(height)));
  358.             y = SPFix(temp.i);
  359.  
  360.             if (!lines)
  361.                if (x != 0 || y != 0)
  362.                   WritePixel(rp2,x+width/2+LEFTW2+3,height/2-y+TOPW2+2);
  363.                else ;
  364.             else
  365.                if (count == 0)
  366.                   Move(rp2,x+width/2+LEFTW2+3,height/2-y+TOPW2+2);
  367.                else
  368.                   Draw(rp2,x+width/2+LEFTW2+3,height/2-y+TOPW2+2);
  369.  
  370.             if (func_num == 0) {  /* z = z^2-u */
  371.                temp.i = SPSub(u_r.i,SPSub(SPMul(z_i.i,z_i.i),SPMul(z_r.i,z_r.i)));
  372.                z_i.i = SPSub(u_i.i,SPMul(SPMul(const2.i,z_r.i),z_i.i));
  373.                z_r = temp;
  374.             }
  375.             else if (func_num == 1) {  /* z = uz(1-z) */
  376.                temp2.i = SPSub(z_r.i,const1.i);
  377.                temp3.i = SPNeg(z_i.i);
  378.                temp.i = SPSub(SPMul(temp3.i,z_i.i),SPMul(temp2.i,z_r.i));
  379.                z_i.i = SPAdd(SPMul(temp2.i,z_i.i),SPMul(temp3.i,z_r.i));
  380.                z_r = temp;
  381.                temp.i = SPSub(SPMul(z_i.i,u_i.i),SPMul(z_r.i,u_r.i));
  382.                z_i.i = SPAdd(SPMul(z_r.i,u_i.i),SPMul(z_i.i,u_r.i));
  383.                z_r = temp;
  384.             }
  385.          }
  386.       }
  387.    }
  388. }
  389.  
  390. ZoomAlongDarling(rzoom, izoom)
  391. int rzoom, izoom;
  392. {
  393.    union kludge center,distance,scale;
  394.  
  395.       scale.i = rzoom;
  396.       distance.i = SPDiv(SPFlt(2),SPSub(start_r.i,end_r.i));
  397.       center.i = SPAdd(start_r.i,distance.i);
  398.       scale.i = SPMul(scale.i,distance.i);
  399.       start_r.i = SPSub(scale.i,center.i);
  400.       end_r.i = SPAdd(scale.i,center.i);
  401.  
  402.       scale.i = izoom;
  403.       distance.i = SPDiv(SPFlt(2),SPSub(start_i.i,end_i.i));
  404.       center.i = SPAdd(start_i.i,distance.i);
  405.       scale.i = SPMul(scale.i,distance.i);
  406.       start_i.i = SPSub(scale.i,center.i);
  407.       end_i.i = SPAdd(scale.i,center.i);
  408. }
  409.  
  410.  
  411.  
  412. int ProjectMenu(code)
  413. ULONG code;
  414. /* if this function calls gen_mand() and it returns non-zero, return a
  415.  * non-zero to the caller, else return zero
  416.  */
  417. {
  418.     ULONG TimeSecs, TimeMicros;
  419.     UBYTE namebuffer[31], numberbuffer[31];
  420.     SHORT namelength;
  421.  
  422.     switch ITEMNUM(code)
  423.        {
  424.        case PROJECT_SAVEPICTURE:
  425.           CurrentTime(&TimeSecs, &TimeMicros);
  426.           stcu_d(&numberbuffer[0], TimeSecs, 31);
  427.           strcpy(&namebuffer[0], "MandPic.");
  428.           namelength = (31 - 1) - strlen(&namebuffer[0]);
  429.           if (namelength > 4) namelength = 4;
  430.           strncat(&namebuffer[0], &numberbuffer[0], namelength);
  431.           strcat(&namebuffer[0], ".");
  432.           stcu_d(&numberbuffer[0], TimeMicros, 31);
  433.           namelength = (31 - 1) - strlen(&namebuffer[0]);
  434.           if (namelength > 1) namelength = 1;
  435.           strncat(&namebuffer[0], &numberbuffer[0], namelength);
  436.           fprintf(console, "*** NAME OF YOUR FILE: %s\n", &namebuffer[0]);
  437.           ScreenToBack(screen);
  438.           if (SavePicture(&namebuffer[0])) ScreenToFront(screen);
  439.           else fprintf(console, "LeftAMIGA-M will redisplay your picture\n");
  440.           break;
  441.        }
  442.     return(0);
  443. }
  444.  
  445.  
  446. int DisplayMenu(code)
  447. ULONG code;
  448. /* if this function calls gen_mand() and it returns non-zero, return a
  449.  * non-zero to the caller, else return zero
  450.  */
  451. {
  452.     switch ITEMNUM(code)
  453.        {
  454.        case OPTIONS_QUARTER:
  455.           if (color_mode & HIRES_MODE) max_x = 640 / 4;
  456.           else max_x = 320 / 4;
  457.           if (color_mode & INTERLACE_MODE) max_y = 400 / 4;
  458.           else max_y = 200 / 4;
  459.           max_mem = max_mem_y * MAXX;
  460.           max_mem /= max_x;
  461.           if (gen_mand()) return(1);
  462.           break;
  463.        case OPTIONS_FULL:
  464.           if (color_mode & HIRES_MODE) max_x = 640;
  465.           else max_x = 320;
  466.           if (color_mode & INTERLACE_MODE) max_y = 400;
  467.           else max_y = 200;
  468.           max_mem = max_mem_y * MAXX;
  469.           max_mem /= max_x;
  470.  
  471.           /* intentionally fall into GENERATE */
  472.        case OPTIONS_GENERATE:
  473.           if (gen_mand()) return(1);
  474.           break;
  475.        case OPTIONS_CLOSE:
  476.           CloseDisplay();
  477.           fclose(v_fp);
  478.           v_fp = NULL;
  479.           return(1);
  480.        case OPTIONS_COLORS:
  481.           DoColorWindow();
  482.           break;
  483.        }
  484.     return(0);
  485. }
  486.  
  487.  
  488. int ZoomMenu(code)
  489. ULONG code;
  490. /* if this function calls gen_mand() and it returns non-zero, return a
  491.  * non-zero to the caller, else return zero
  492.  */
  493. {
  494.     union kludge center, distance, scale;
  495.  
  496.     switch ITEMNUM(code)
  497.        {
  498.        case ZOOM_SETCENTER:
  499.           if (NOT SettingCenter)
  500.              {
  501.              ZoomCenterX = w->MouseX;
  502.              ZoomCenterY = w->MouseY;
  503.              DrawDisplayCenter();
  504.              DrawZoomCenter();
  505.              SettingCenter = TRUE;
  506.              }
  507.           break;
  508.        case ZOOM_SIZEBOX:
  509.        case ZOOM_SIZEPROP:
  510.           if (NOT SettingBoxSize)
  511.              {
  512.              if (ITEMNUM(code) == ZOOM_SIZEPROP) SetBoxProportional = TRUE;
  513.              else SetBoxProportional = FALSE;
  514.              SettingBoxSize = TRUE;
  515.              RecalcZoomBox();
  516.              DrawZoomBox();
  517.              }
  518.           break;
  519.        case ZOOM_ZOOMIN:
  520.        case ZOOM_ZOOMIN10:
  521.           /* first, get distance equal to the current size 
  522.            * of a single pixel width 
  523.            */
  524.           distance.i = SPSub(start_r.i,end_r.i);
  525.           distance.i = SPDiv(SPFlt(max_x), distance.i);
  526.           /* center equals the number of pixels from the
  527.            * center of the display to the zoom center
  528.            */
  529.           center.i = SPSub(SPFlt(max_x >> 1), SPFlt(ZoomCenterX));
  530.           /* scale equals the real displacement from the
  531.            * center of the display to the zoom center
  532.            */
  533.           scale.i = SPMul(distance.i, center.i);
  534.           /* move the real origin to here */
  535.           start_r.i = SPAdd(scale.i,start_r.i);
  536.           end_r.i = SPAdd(scale.i,end_r.i);
  537.  
  538.           /* now do it all again for the irrational axis */
  539.           distance.i = SPSub(start_i.i,end_i.i);
  540.           distance.i = SPDiv(SPFlt(max_y), distance.i);
  541.           /* the signs are reversed to swap the sign */
  542.           center.i = SPSub(SPFlt(ZoomCenterY), SPFlt(max_y >> 1));
  543.           scale.i = SPMul(distance.i, center.i);
  544.           /* move the real origin to here */
  545.           start_i.i = SPAdd(scale.i,start_i.i);
  546.           end_i.i = SPAdd(scale.i,end_i.i);
  547.  
  548.           /* next, get the zoom-in scale
  549.            * if we're using the frame, then get the 
  550.            * proportion of the box to the display;
  551.            * else if we're zooming in by 10, get that scale
  552.            */
  553.           if (ITEMNUM(code) == ZOOM_ZOOMIN)
  554.              scale.i = SPDiv(SPFlt(max_x), SPFlt(ZoomBoxSizeX));
  555.           else scale.i = SPDiv(SPFlt(10), SPFlt(1));
  556.           ZoomAlongDarling(scale.i, SPFlt(1));
  557.           if (ITEMNUM(code) == ZOOM_ZOOMIN)
  558.              scale.i = SPDiv(SPFlt(max_y), SPFlt(ZoomBoxSizeY));
  559.           else scale.i = SPDiv(SPFlt(10), SPFlt(1));
  560.           ZoomAlongDarling(SPFlt(1), scale.i);
  561.  
  562.           if (gen_mand()) return(1);
  563.           break;
  564.        case ZOOM_ZOOMOUT2:
  565.           ZoomAlongDarling(SPFlt(2), SPFlt(2));
  566.           if (gen_mand()) return(1);
  567.           break;
  568.        case ZOOM_ZOOMOUT10:
  569.           ZoomAlongDarling(SPFlt(10), SPFlt(10));
  570.           if (gen_mand()) return(1);
  571.           break;
  572.        }
  573.    return(0);
  574. }
  575.